package com.hxlc.util;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 时间转换
 */
public class DateConvertUtil {

    public final static String FORMAT6 = "yyyyMM";
    public final static String FORMAT_8 = "yyyyMMdd";
    public final static String FORMAT_10 = "yyyy-MM-dd"; // 年月日
    public final static String FORMAT_8_CN = "yyyy年MM月dd日"; // 年月日
    public final static String FORMAT_16 = "yyyy-MM-dd HH:mm:ss"; // 年月日
    public final static String FORMAT_10_h = "yyyyMMddhh"; // 年月日
    public final static String FORMAT_10_h_CN= "yyyy年MM月dd日hh时"; // 年月日时
    public final static String FORMAT_10_H = "yyyyMMddHH"; // 年月日
    public final static String FORMAT_10_H_CN= "yyyy年MM月dd日HH时"; // 年月日时
    public final static String FORMAT14 = "yyyyMMddhhmmss";
    public final static String FORMAT14_ = "yyyyMMddHHmmss";
    public final static String FORMAT10_ = "yyyyMMddHH";
    public final static String FORMAT12 = "yyyyMMddHHmm";



    public static Calendar getInstance(Date date){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar;
    }


    public static Date calendarDaate(Calendar calendar){
        return calendar.getTime();
    }

    /**
     *描述 时间字符串转换为时间格式
     *参数
     *返回值
     *创建人  zhouyongbo
     *创建时间  2018/9/28
     *修改人和其它信息
     */
    public static Timestamp formatStringToTimestamp(Object date, String format){
        if (date == null ){
            return null;
        }
        Date nDate = formatStringToDate(date.toString(), format);
        if (nDate == null){
            return null;
        }
        return new Timestamp(nDate.getTime());
//        return new Timestamp();
    }

    /**
     *
     * @param date
     * @param format
     * @param conFormat
     * @return
     */
    public static String formatStringToString(String date,String format,String conFormat){
        return formatDateToString(formatStringToDate(date,format),conFormat);
    }

    /**
     *描述 时间字符串转换为时间格式
     *参数
     *返回值
     *创建人  zhouyongbo
     *创建时间  2018/9/28
     *修改人和其它信息
     */
    public static Date formatStringToDate(Object date,String format){
        if (date == null ){
            return null;
        }
        return formatStringToDate(date.toString(),format);
    }

    /**
     *描述 时间字符串转换为时间格式
     *参数
     *返回值
     *创建人  zhouyongbo
     *创建时间  2018/9/28
     *修改人和其它信息
     */
    public static Date formatStringToDate(String date,String format){
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        try {
            return formatter.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Calendar formatStringToCalendar(String date,String format){
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        try {
            Date date1 = formatter.parse(date);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date1);
            return calendar;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     *描述 时间字符串转换为时间格式
     *参数
     *返回值
     *创建人  zhouyongbo
     *创建时间  2018/9/28
     *修改人和其它信息
     */
    public static String formatDateToString(Date date,String format){
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        return formatter.format(date);
    }


    /**
     *描述 求两个时间相差的天数
     *参数
     *返回值
     *创建人  zhouyongbo
     *创建时间  2018/9/28
     *修改人和其它信息
     */
    public static int differenceValue(Date startDate,Date endDate){
        return (int)((endDate.getTime()-startDate.getTime())/(24*3600*1000));
    }


    public static String[] countDays(Date startDate,int days){
        String[] dayArr = new String[days];
        for (int i = 0 ;i<days;i++){
            dayArr[i] =  formatDateToString(new Date(startDate.getTime()+i*24*3600*1000L)
                    , FORMAT_10);
        }
        return dayArr;
    }
    public static String[] countDays(Date startDate,int days, String format){
        String[] dayArr = new String[days];
        for (int i = 0 ;i<days;i++){
            dayArr[i] =  formatDateToString(new Date(startDate.getTime()+i*24*3600*1000L)
                    , format);
        }
        return dayArr;
    }


    /**
     * 获取年份
     * @param date
     * @return
     */
    public static Integer getYear(Date date){
        return getInstance(date).get(Calendar.YEAR);
    }

    /**
     * 获取月份
     * @param date
     * @return
     */
    public static Integer getMonth(Date date){
        return getInstance(date).get(Calendar.MONTH)+1;
    }

    /**
     * 获取月日
     */
    public static Integer getMonthAndDay(Date date){
        Integer month = getInstance(date).get(Calendar.MONTH)+1;
        Integer day = getInstance(date).get(Calendar.DATE);
        Integer monthAndDay = Integer.parseInt(""+month+day);
        if(day<10){
            monthAndDay = Integer.parseInt(""+month+"0"+day);
        }
        return monthAndDay;
    }

    /**
     * 获取小时
     * @param date
     * @return
     */
    public static Integer getHourOfDay(Date date){
        Calendar calendar = getInstance(date);
        return calendar.get(Calendar.HOUR_OF_DAY);
    }

    /**
     * 获取这个月的天数
     * @param date
     * @return
     */
    public static Integer getMonthDay(Date date){
        Calendar calendar = getInstance(date);
        calendar.set(calendar.get(Calendar.YEAR),calendar.get(Calendar.MONTH)+1,0);
       return calendar.get(Calendar.DAY_OF_MONTH);
    }


    /**
     * 计算日期
     */
    public static String calculateMonth(String time, String format,Integer days){
        Date date = formatStringToDate(time, format);
        date = new Date(date.getTime()+days*24*3600*1000L);
        return formatDateToString(date,format);
    }

    /**
     * 计算日期
     * @param time
     * @param days
     * @return
     */
    public static Long calculateDays(Long time, Integer days){
        time = time/1000000;
        int year = (int) (time/10000);
        int month = (int )((time%10000)/100);
        int day = (int) ((time%10000)%100);
        Date date =  formatYearAndMonthAndDayToDate(year,month,day);
        date = new Date(date.getTime()+days*24*3600*1000L);
        return Long.valueOf(formatDateToString(date,DateConvertUtil.FORMAT_8)+"000000");
    }

    /**
     * 计算小时
     * @param time
     * @param hours
     * @return  2020071808
     */
    public static Long calculateHours(Long time, Integer hours){
        time = time/10000;
        int year = (int) (time/1000000);
        int month = (int )((time%1000000)/10000);
        int day = (int) ((time%10000)/100);
        int hour = (int)(time%100);
        Date date =  formatYearAndMonthAndDayAndHourToDate(year,month,day,hour);
        date = new Date(date.getTime()+hours*3600*1000L);
        return Long.valueOf(formatDateToString(date,DateConvertUtil.FORMAT10_)+"0000");
    }

    /**
     * 计算分钟
     * @param time
     * @param minutes
     * @return  time 202011131125
     */
    public static Long calculateMinutes(Long time, Integer minutes){
        time = time/100;
        int year = (int) (time/100000000);
        int month = (int )((time%100000000)/1000000);
        int day = (int) ((time%1000000)/10000);
        int hour = (int)((time%10000)/100);
        int minute = (int)(time%100);
        Date date =  formatYearAndMonthAndDayAndHourAndMinuteToDate(year,month,day,hour,minute);
        date = new Date(date.getTime()+minutes*60*1000L);
        return Long.valueOf(formatDateToString(date,DateConvertUtil.FORMAT12)+"00");
    }

    /**
     * 分钟切割
     * @return
     */
    public static long[] getGroupMinutes(Long startTime,Long endTime,Integer minutes){
        List<Long> minutesGroup = new ArrayList<>();
        if(new BigDecimal(endTime).compareTo(new BigDecimal(startTime)) != 1){
            return Arrays.stream(minutesGroup.toArray(new Long[minutesGroup.size()])).mapToLong(s -> Long.valueOf(s)).toArray();
        }
        while (new BigDecimal(endTime).compareTo(new BigDecimal(startTime)) != -1){
            minutesGroup.add(startTime);
            startTime = calculateMinutes(startTime,minutes);
        }
        return Arrays.stream(minutesGroup.toArray(new Long[minutesGroup.size()])).mapToLong(s -> Long.valueOf(s)).toArray();
    }

    /**
     * 分钟切割
     * @return
     */
    public static long[] getGroupMinutesTimestamp(Long startTime,Long endTime,Integer minutes){
        List<Long> minutesGroup = new ArrayList<>();
        if(new BigDecimal(endTime).compareTo(new BigDecimal(startTime)) != 1){
            return Arrays.stream(minutesGroup.toArray(new Long[minutesGroup.size()])).mapToLong(s -> Long.valueOf(s)).toArray();
        }
        while (new BigDecimal(endTime).compareTo(new BigDecimal(startTime)) == 1){
            minutesGroup.add(startTime);
            startTime = startTime + minutes*60*1000;
        }
        return Arrays.stream(minutesGroup.toArray(new Long[minutesGroup.size()])).mapToLong(s -> Long.valueOf(s)).toArray();
    }

    public static Integer calculateDays(Object startTime,Object endTime,String format){
        Date startDate = formatStringToDate(startTime, format);
        Date endDate = formatStringToDate(endTime, format);
        return Math.abs((int)(endDate.getTime() - startDate.getTime() / (24 * 3600 * 1000L)));
    }

    /**
     *
     * @param year YYYY
     * @param days MMDD
     * @param day  计算的增加量
     * @return
     */
    public static Integer calculateDays(Integer year,Integer days,int day){
        String time = formatYearAndMonthAndDayToDate(year, days / 100, days % 100 - day, FORMAT14_);
        return Integer.valueOf(time.substring(4,8));
    }

    public static String formatYearAndMonthAndDayToDate(Integer year, int month, int day, String format) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year,month-1,day);
        return formatDateToString(calendar.getTime(),format);
    }

    public static Date formatYearAndMonthAndDayToDate(Integer year, int month, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year,month-1,day);
        return calendar.getTime();
    }

    public static Date formatYearAndMonthAndDayAndHourToDate(Integer year, int month, int day ,int hour) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year,month-1,day,hour,0);
        return calendar.getTime();
    }

    public static Date formatYearAndMonthAndDayAndHourAndMinuteToDate(Integer year, int month, int day ,int hour,int minute) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(year,month-1,day,hour,minute);
        return calendar.getTime();
    }

    public static Integer getMeadowByTime(String time,String format){
        Calendar calendar = formatStringToCalendar(time,format);
        if(calendar == null){
            return null;
        }
        Integer day = calendar.get(Calendar.DATE);
        if(day <= 10){
            return Integer.parseInt((calendar.get(Calendar.MONTH) + 1) + "01");
        }else if(day > 10 && day <= 20){
            return Integer.parseInt((calendar.get(Calendar.MONTH) + 1) + "02");
        }else {
            return Integer.parseInt((calendar.get(Calendar.MONTH) + 1) + "03");
        }
    }

    public static Integer getseasonByMonth(Integer month){
        if(month == null){
            return null;
        }
        if(month >= 3 && month <= 5){
            return 1;
        }else if(month >= 6 && month <= 8){
            return 2;
        }else if(month >= 9 && month <= 11){
            return 3;
        }else {
            return 4;
        }
    }

    public static Integer getSquerySeasonYear(Integer month, Integer collectYear) {
        if(month == null || collectYear == null){
            return null;
        }
        if(month <= 2){
            return collectYear - 1;
        }
        return collectYear;
    }

    public static List<Integer> getTimeListByStartAndEnd(Integer startYear, Integer endYear) {
        if(startYear > endYear){
            return null;
        }
        List<Integer> list = new ArrayList<>();
        for(Integer i = startYear;i<=endYear;i++){
            list.add(i);
        }
        return list;
    }

}
